package org.jeecg.modules.simulator.rooter;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.jeecg.modules.common.CommonMQTTConstant;
import org.jeecg.modules.mqtt.MQTTUtils;
import org.jeecg.modules.simulator.Simulator;
import org.jeecg.modules.simulator.factory.DataBizFactory;

import org.jeecg.modules.simulator.factory.person.GodAssistanter;
import org.jeecg.modules.simulator.jsonot.*;
import org.jeecg.modules.simulator.loader.AddTrainPointType;
import org.jeecg.modules.simulator.loader.SimpleAddTrainData;

import org.jeecg.modules.simulator.loader.StationParamOperate;
import org.jeecg.modules.simulator.model.MetroTrain;
import org.jeecg.modules.simulator.model.OffTrainNumRange;
import org.jeecg.modules.simulator.model.SceneParam;
import org.jeecg.modules.simulator.model.SimulatorParam;
import org.jeecg.modules.simulator.model.line.Line;
import org.jeecg.modules.simulator.model.line.park.Parker;
import org.jeecg.modules.simulator.model.line.station.station.Station;
import org.jeecg.modules.simulator.model.line.station.station.TransferStation;
import org.jeecg.modules.simulator.model.orbit.OrbitPoint;
import org.jeecg.modules.simulator.model.person.Person;
import org.jeecg.modules.simulator.model.person.path.PersonPath;
import org.jeecg.modules.simulator.model.person.path.PersonPathItem;

import org.jeecg.modules.simulator.model.train.TrainPhysics;
import org.jeecg.modules.simulator.model.train.event.TrainListener;
import org.jeecg.modules.simulator.model.train.event.TrainRecordEvent;
import org.jeecg.modules.simulator.model.train.timeplan.TrainPlanTable;
import lombok.Getter;
import lombok.Setter;

import org.jeecg.modules.simulator.recorder.Reacorder;
import org.jeecg.modules.simulator.recorder.event.OutputWriteFileEvent;
import org.jeecg.modules.simulator.service.HistoryBizPersonLoaderService;
import org.jeecg.modules.simulator.service.HistoryBizTrainLoaderService;
import org.jeecg.modules.simulator.service.QueryPasgrPeriodServiceImpl;
import org.jeecg.modules.simulator.service.T80RouteHisService;
import org.jeecg.modules.simulator.util.SpringUtil;
import org.jeecg.modules.simulator.util.TimeUtil;
import org.jeecg.modules.simulator.util.UnitCache;
import org.jeecg.modules.simulator.vo.*;
import org.springframework.data.redis.core.RedisTemplate;


import java.time.Duration;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: gp2
 * @description:
 * @author: renzhg
 * @create: 2024-08-29 08:56
 **/

public class NetRooter implements Simulator {
    @Setter
    @Getter
    String sceneCode;

    @Getter
    @Setter
    TrainListener trainListener;
    @Getter
    Map<String, OffTrainNumRange> offTrainNumRangeMap;
    @Setter
    SimulatorParam simulatorParam;
    LocalTime currentTime;


    @Getter
    God god=new God();
    @Getter
    GodAssistanter godAssistanter = new GodAssistanter();

    @Setter
    QueryPasgrPeriodServiceImpl queryPasgrPeriodService;
    @Getter
    @Setter
    private RedisTemplate<String, Object> redisTemplate;

    RootPublisher rootPublisher = new RootPublisher();
    @Setter
    Reacorder reacorder;

     int inputNetTotal=0;

    @Getter
    @Setter
    //全天客流量，需要从场景参数中获取
    Integer dailyPassengerVolume;
    @Getter
    @Setter
    Integer netAllPersonSizePSec = 0;
    @Getter
    @Setter
    HistoryBizTrainLoaderService historyBizTrainLoaderService;
    @Getter
    @Setter
    HistoryBizPersonLoaderService historyBizPersonLoaderService;


//    @Getter
//    @Setter
//    RedisTemplate<String, Object> redisTemplate;





    DataBizFactory dataBizLoader = new DataBizFactory();

    @Getter
    Map<String, Integer> netAllPersonSizePSecMap = new HashMap<>();


    @Getter
    Map<String, Map<String, NumPeopEnStationApiInfo>> numPeopEnStationApiInfoMap = new HashMap<>();

    //进站里面人数的OD概率
    @Setter
    Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfoMap = new HashMap<>();
    @Setter
    Map<String, List<TrainPlanTable>> trainPlanTableMapByLine = new HashMap<>();
    Map<String, List<OrbitPoint>> orbitPointListMap = new HashMap<>();
    Map<String, List<OrbitPoint>> orbitPointAllListMap = new HashMap<>();


    List<LineCurInfoVo> lineCurInfoVoList = new ArrayList<>();//线路中当前车辆信息
    Map<String, Line> lineMap = new HashMap<>();

    Map<String, Line> lineAllMap = new HashMap<>();
    //换乘站集合
    Map<String, TransferStation> transferStationMap = new HashMap<>();//换乘站集合


//    Map<String, TransferStation> transferAllStationMap = new HashMap<>();//换乘站集合
    //换乘站名称字典集合
    Map<String, TransferStation> transferNameStationMap = new HashMap<>();



    //总station集合，使用的是stationId,做key
    Map<String, Station> stationMap = new HashMap<>();
    Map<String, Station> stationAllMap = new HashMap<>();


    //stationName,使用站名做Key
    Map<String, Station> stationNameMap = new HashMap<>();
    //线路和站名做Key
    Map<String, Station> stationLineStaionNameMap = new HashMap<>(); //线路和站名做Key
    Map<String, Station> stationAllLineStaionNameMap = new HashMap<>();


    @Getter
    //按线路Id做的LineRooter
    Map<String, LineRooter> lineRooterMap = new HashMap<>();
    //未分配的列车
    Map<String, List<MetroTrain>> metroTrainNoAssigeMap = new HashMap<>();
    //按线路分配的场段字典
    Map<String, List<Parker>> parkerMap = new HashMap<>();
    Map<String, List<Parker>> parkerAllMap = new HashMap<>();
    //按id为key做的场段字典，给trainListener使用的
    Map<String, Parker> parkersMap = new HashMap<>();


    //按id为key做的场段字典，给trainListener使用的
    Map<String, Parker> parkersAllMap = new HashMap<>();
    //历史人员走行路径,key:为站
    Map<String, List<PersonPath>> historyPersonPathMap = new HashMap<>();

    //key:路径序号+首站点名称
    Map<String, PersonPath> personPathMap = new HashMap<>();
    //key:路径序号+首站点id
    Map<String, PersonPath> personPathIdMap = new HashMap<>();
    Map<String, TrainPhysics> trainPhysicsMap = new HashMap<>();
    //按线路分的station
    Map<String, List<Station>> linesStationMap = new HashMap<>();
    Map<String, List<Station>> linesAllStationMap = new HashMap<>();
//    @Getter
//    Map<String, List<RouteStation>> t80RouteHisMap = new HashMap<>();



    Map<String, List<PsgStationDistributionInfo>> psgStationDistributionInfoMap = new HashMap<>();








    @Getter
    String netStartTrainTime;
    @Getter
    Map<String, String> startTimeMap = new HashMap<>();

    @Getter
    //key:列车id，第二个key：阶段路线起始站（可以是换乘站或者开始站）-下车车站名
    Map<String, Map<String, List<Person>>> personTrainMapByLine = new HashMap<>();
    /**
     * @description: 未分配的列车
     * @author: renzhg
     * @date: 2024/8/30 13:54
     **/
    @Getter
    Map<String, List<MetroTrain>> noAssignMetroTrainMap = new HashMap<>();//key:场段ID



    //region  加载数据
    //数据从全局缓冲中读取出来
    public void loadBasicData() {
        loadDb();
    }


    public void LoadPersons(){
//        godAssistanter.setRedisTemplate(this.redisTemplate);
        godAssistanter.setSceneCode(sceneCode);
        godAssistanter.setLineMap(this.lineMap);
        godAssistanter.setHistoryBizPersonLoaderService(historyBizPersonLoaderService);
        godAssistanter.loadODAssignPerson();
        godAssistanter.loadEntryStationNum();
        godAssistanter.loadAllDayPersonHistory();
        this.odProbabilityApiInfoMap=godAssistanter.getOdProbabilityApiInfosFilterMap();
        numPeopEnStationApiInfoMap=godAssistanter.getNumPeopEnStationApiInfoMap();



    }

    public void loadDb() {
        trainPhysicsMap = UnitCache.globalSceneBaseData.getTrainPhysicsMap();
        lineAllMap = UnitCache.globalSceneBaseData.getLineMap();//全部线路数据
//        transferStationMap = UnitCache.globalSceneBaseData.getTransferStationMap();
        transferStationMap = UnitCache.globalSceneBaseData.getTransferStationMap();//全部换乘站数据
//        linesStationMap=UnitCache.globalSceneBaseData.getLineStationMap();
        linesAllStationMap = UnitCache.globalSceneBaseData.getLineStationMap();
        transferStationMap.forEach((k, v) -> {
//            transferNameStationMap.put(v.getName(), v);
            transferNameStationMap.put(v.getName(), v);
        });
//        stationMap.clear();
        stationAllMap.clear();
//        stationMap = linesStationMap.values()
//                .stream()
//                .flatMap(List::stream)
//                .collect(Collectors.toMap(Station::getId, station -> station));

        stationAllMap = linesAllStationMap.values()
                .stream()
                .flatMap(List::stream)
                .collect(Collectors.toMap(Station::getId, station -> station));

//        stationLineStaionNameMap = linesStationMap.entrySet().stream()
//                .flatMap(entry -> entry.getValue().stream()
//                        .map(station -> new AbstractMap.SimpleEntry<>(
//                                station.getName() + "_" + station.getLine(),
//                                station))).collect(Collectors.toMap(
//                        Map.Entry::getKey,
//                        Map.Entry::getValue,
//                        (existing, replacement) -> existing // 处理键冲突，这里选择保留已有的
//                ));

        stationAllLineStaionNameMap = linesAllStationMap.entrySet().stream()
                .flatMap(entry -> entry.getValue().stream()
                        .map(station -> new AbstractMap.SimpleEntry<>(
                                station.getName() + "_" + station.getLine(),
                                station))).collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (existing, replacement) -> existing // 处理键冲突，这里选择保留已有的
                ));


//        parkerMap = UnitCache.globalSceneBaseData.getParkerMap();

        parkerAllMap = UnitCache.globalSceneBaseData.getParkerMap();


//        List<Parker> parkerList = parkerMap.values()
//                .stream()
//                .flatMap(List::stream)
//                .collect(Collectors.toList());
        List<Parker> parkerList = parkerAllMap.values()
                .stream()
                .flatMap(List::stream)
                .collect(Collectors.toList());

//        parkersMap = parkerList.stream()
//                .collect(Collectors.toMap(
//                        Parker::getId,
//                        parker -> parker,
//                        (existing, replacement) -> replacement // 如果有冲突，使用新的值
//                ));
        parkersAllMap = parkerList.stream()
                .collect(Collectors.toMap(
                        Parker::getId,
                        parker -> parker,
                        (existing, replacement) -> replacement // 如果有冲突，使用新的值
                ));

//        orbitPointListMap=UnitCache.globalSceneBaseData.getOrbitPointListMap();
        orbitPointAllListMap = UnitCache.globalSceneBaseData.getOrbitPointListMap();
//        this.t80RouteHisMap =  UnitCache.globalSceneBaseData.getT80RouteHisMap();
//        System.out.println( this.t80RouteHisMap.size());

    }



//    public void dataLoadRootInit(){
//
//
//    }

    public void filterBasicData() {
        SimulatorParam simulatorParam1 = UnitCache.simulatorParamMap.get(sceneCode);
        List<String> showLines = simulatorParam1.getShowLines();
        lineAllMap.forEach((k, v) -> {
            if (showLines.contains(k)) {
                lineMap.put(k, v);
            }
        });
//        transferAllStationMap.forEach((k,v)->{
//
//
//            boolean b = showLines.containsAll(v.getTransferStationMap().keySet());
//            if(b){
//                transferStationMap.put(k,v);
//            }
//
////            if(showLines.contains(v.getLine())){
////                transferStationMap.put(k,v);
////            }
//        });

        linesAllStationMap.forEach((k, v) -> {
            if (showLines.contains(k)) {
                linesStationMap.put(k, v);
            }
        });
        stationMap.clear();
        stationAllMap.forEach((k, v) -> {
            if (showLines.contains(v.getLine())) {
                stationMap.put(k, v);
            }
        });

        stationAllLineStaionNameMap.forEach((k, v) -> {
            if (showLines.contains(v.getLine())) {
                stationLineStaionNameMap.put(k, v);
            }
        });

        parkerAllMap.forEach((k, v) -> {
            if (showLines.contains(v.get(0).getLineId())) {
                parkerMap.put(k, v);
            }
        });
        parkersAllMap.forEach((k, v) -> {
            if (showLines.contains(v.getLineId())) {
                parkersMap.put(k, v);
            }
        });
        orbitPointAllListMap.forEach((k, v) -> {
            if (showLines.contains(k)) {
                orbitPointListMap.put(k, v);
            }
        });

    }


    //region 初始化数据

    //初始化业务数据



    /**
     * @description: 计算每秒进网人数, 用全天进网络
     * @author: renzhg
     * @date: 2024/9/10 17:50
     **/

    public int getAverageNetAllPersonSizePSec(LocalTime startTime, LocalTime endTime) {
        long secondsBetween = Duration.between(startTime, endTime).getSeconds();
        int averageNetAllPersonSizePSec = (int) (dailyPassengerVolume / secondsBetween); //
        return averageNetAllPersonSizePSec;

    }

    /**
     * @description: 计算每秒进站人数, 用全天每秒进网络
     * @author: renzhg
     * @date: 2024/9/10 17:50
     **/
    public void generateNetAllPersonSizePSecMap() {
        int personSize = (int) netAllPersonSizePSec / stationMap.size();
        stationMap.forEach((k, v) -> {
            netAllPersonSizePSecMap.put(k, personSize);
        });
    }

    //endregionfd



//    public void DMRInit(){
//
//
//
//    }

    //检查加车请求参数
    public void checkAddTrainReqParam(String now) {
        SimpleAddTrainData simpleAddTrainData = UnitCache.simpleAddTrainDataMap.get(sceneCode);
        if (simpleAddTrainData == null) {
            return;
        } else {
            if (simpleAddTrainData.getAddTrainPointType().equals(AddTrainPointType.park)) {
                parkerMap.forEach((k, v) -> {
                    if (k.equals(simpleAddTrainData.getAddLineId())) {
                        TrainManager trainManager = this.lineRooterMap.get(k).getTrainManager();
                        v.forEach(o -> {
                            if (o.getId().equals(simpleAddTrainData.getAddId())) {
                                TrainPlanTable trainPlanTable = new TrainPlanTable();
                                trainPlanTable.setTrainId(simpleAddTrainData.getAddTrainId());
                                trainPlanTable.setTrainNum(simpleAddTrainData.getAddTrainNum());
                                trainPlanTable.setArriveTime(simpleAddTrainData.getAddTrainArriveTime());
                                trainPlanTable.setDepartTime(simpleAddTrainData.getAddTrainDepartTime());
                                trainPlanTable.setLineId(simpleAddTrainData.getAddLineId());

                                if (simpleAddTrainData.isUp()) {
                                    trainPlanTable.setArriveStaionName(o.getUpOut().getName());
                                    trainPlanTable.setArrivateStaionId(o.getUpOut().getId());
                                }
                                trainPlanTable.setIndex(1);
                                int remainTime = TimeUtil.calculateSecondsDifference(simpleAddTrainData.getAddTrainArriveTime(), simpleAddTrainData.getAddTrainDepartTime());
                                trainPlanTable.setRemainTime(remainTime);


                                long planSpeed = Long.parseLong(simpleAddTrainData.getAddTrainSpeed());

                                trainManager.addSimplePlanTable(trainPlanTable, planSpeed,now);
                            }
                        });
                    }
                });
            }

            //使用完数据置空
            UnitCache.simpleAddTrainDataMap.put(sceneCode, null);

        }

    }
    public LineStaticInfoVo afterInitGetLineStaticInfo() {
        LineStaticInfoVo lineStaticInfoVo = new LineStaticInfoVo();
        Map<String,Integer> lineStationNumMap = new HashMap<>();
        List<String> lineStationNumList=new ArrayList<>();

        lineMap.forEach((k,v)->{
//            lineStationNumMap.put(k,v.getStationMap().size());
            lineStationNumList.add(k+"-"+v.getStationMap().size());
        });
//        lineStaticInfoVo.setLineStationNumMap(lineStationNumMap);
        int currentStationNum =stationAllMap.size();
        lineStaticInfoVo.setCurrentOpenStationNum(currentStationNum);
        List<String> stationNameList = new ArrayList<>();
        stationNameList.add("一号线-十三号街车辆段");
        stationNameList.add("二号线-浑南车辆段;桃仙停车场");
        stationNameList.add("四号线-文官屯车辆段;航天南路停车场");
        stationNameList.add("九号线-曹仲车辆段");
        stationNameList.add("十号线-桑林子车辆段;丁香湖停车场");
        lineStaticInfoVo.setControlDepotNameList(stationNameList);
//        Map<String,String> controlDepotNameMap = new HashMap<>();
//        controlDepotNameMap.put("1号线","十三号街车辆段");
//        controlDepotNameMap.put("2号线","浑南车辆段;桃仙停车场");
//        controlDepotNameMap.put("4号线","文官屯车辆段;航天南路停车场");
//        controlDepotNameMap.put("9号线","曹仲车辆段");
//        controlDepotNameMap.put("10号线","桑林子车辆段;丁香湖停车场");



//        lineStaticInfoVo.setControlDepotNameMap(controlDepotNameMap);
//        Map<String,Integer> NumberOfVehiclesMap = new HashMap<>();
        List<String> NumberOfVehiclesList=new ArrayList<>();
        NumberOfVehiclesList.add("一号线-"+23);
        NumberOfVehiclesList.add("二号线-"+74);
        NumberOfVehiclesList.add("四号线-"+35);
        NumberOfVehiclesList.add("九号线-"+30);
        NumberOfVehiclesList.add("十号线-"+27);
        lineStaticInfoVo.setNumberOfVehiclesList(NumberOfVehiclesList);
//        NumberOfVehiclesMap.put("1号线",23);
//        NumberOfVehiclesMap.put("2号线",74);
//        NumberOfVehiclesMap.put("4号线",35);
//        NumberOfVehiclesMap.put("9号线",30);
//        NumberOfVehiclesMap.put("10号线",27);
//        lineStaticInfoVo.setNumberOfVehiclesMap(NumberOfVehiclesMap);

        Map<String,Integer> NumberOfTrainsInLineMap=new HashMap<>();
        List<String> NumberOfTrainsInLineList=new ArrayList<>();

        getLineRooterMap().forEach((k,v)->{
            NumberOfTrainsInLineMap.put(k,v.getTrainManager().getTrainMap().size());
            NumberOfTrainsInLineList.add(k+"-"+v.getTrainManager().getTrainMap().size());

        });

//        lineStaticInfoVo.setNumberOfTrainsInLineMap(NumberOfTrainsInLineMap);
        lineStaticInfoVo.setNumberOfTrainsInLineList(NumberOfTrainsInLineList);
        return lineStaticInfoVo;
    }
    @Override
    public LocalTime getCurrentTime() {
        return currentTime;
    }

    @Override
    public void UpdateCurrentTime(LocalTime currentTime) {
        this.currentTime = currentTime;
    }

    @Override
    public void nextTime(String now, Integer step) {

        SceneParam sceneParam = UnitCache.sceneParamMap.get(sceneCode);
        LocalTime startTime = sceneParam.getStartTime();
//        long startTime_checkAddTrainReqParam = System.nanoTime();//检查这个站是否有
        //检查是否有简单加车请求参数
        checkAddTrainReqParam(now);
//        long endTime_checkAddTrainReqParam = System.nanoTime();
//        long duration1 = endTime_checkAddTrainReqParam - startTime_checkAddTrainReqParam;
//        System.out.println("程序运行时间: checkAddTrainReqParam=" + duration1  / 1_000_000+" 毫秒");
//        long startTime_checkStationStatus = System.nanoTime();//检查这个站是否有
        //检查站点状态控制
        checkStationStatus();
//        long endTime_checkStationStatus = System.nanoTime();
//        long duration_checkStationStatus = endTime_checkStationStatus - startTime_checkStationStatus;
//
//        System.out.println("程序运行时间: checkStationStatus=" + duration_checkStationStatus  / 1_000_000+" 毫秒");

        long startTime_god = System.nanoTime();//检查这个站是否有


        god.nextTime(now,step);


        long endTime_god = System.nanoTime();
        long duration_god = endTime_god - startTime_god;
        System.out.println("程序运行时间: god=" + duration_god  / 1_000_000+" 毫秒");

//        long startTime_lineRooterMap = System.nanoTime();//检查这个站是否有

        lineRooterMap.forEach((k, v) -> {
            v.nextTime(now, step);
        });
//        long endTime_lineRooterMap = System.nanoTime();
//        long duration_lineRooterMap = endTime_lineRooterMap - startTime_lineRooterMap;
//        System.out.println("程序运行时间: lineRooterMap=" + duration_lineRooterMap  / 1_000_000+" 毫秒");

//        long startTime_transferStationMap = System.nanoTime();//检查这个站是否有
        transferStationMap.forEach((k, v) -> {
            v.UpdateCurrentTime(this.getCurrentTime());
            v.nextTime(now, step);
        });
//        long endTime_transferStationMap = System.nanoTime();
//        long duration_transferStationMap = endTime_transferStationMap - startTime_transferStationMap;
//        System.out.println("程序运行时间: transferStationMap=" + duration_transferStationMap  / 1_000_000+" 毫秒");
        long startTime_dataSendAndRecord = System.nanoTime();//检查这个站是否有
        //数据发送并且记录
        dataSendAndRecord( now,  startTime,  sceneParam);
        long endTime_dataSendAndRecord = System.nanoTime();
        long duration_dataSendAndRecord = endTime_dataSendAndRecord - startTime_dataSendAndRecord;
        System.out.println("程序运行时间: dataSendAndRecord=" + duration_dataSendAndRecord  / 1_000_000+" 毫秒");

    }


    //数据发送与记录
    public void dataSendAndRecord(String now, LocalTime startTime, SceneParam sceneParam){
        //mqtt数据发送
        OutputWriteFileObject  outputWriteFileObject= sendMQTTDataAndPrint( now,startTime, sceneParam);
        //本地硬盘数据输出
        if(outputWriteFileObject!=null){
            print2LocalFine(now,outputWriteFileObject);
        }

//        print2LocalStorage(now,startTime);
        //线路静态数据更新
        lineStaticDataUpdate();
    }



    public void print2LocalFine(String now,OutputWriteFileObject outputWriteFileObject){
        SpringUtil.getApplicationContext().publishEvent(new OutputWriteFileEvent(outputWriteFileObject));
        rootPublisher.trainRecorderPublish(now);
    }

    //mqtt数据发送并且本地打印
    public  OutputWriteFileObject  sendMQTTDataAndPrint(String now, LocalTime startTime, SceneParam sceneParam) {




            System.out.println("测试");
        rootPublisher.sendCurrentTime(now, this.sceneCode);//发送时间方法
        rootPublisher.trainRecorderPublish(now);
        //发送时间进度条
        rootPublisher.caculatePercentage(now, sceneParam);
        List<TrainCurInfoVo> trainCurInfoVos = rootPublisher.getTrainCurInfoVoList(now);
        LocalTime localTime = LocalTime.parse(now);
        if(startTime.isBefore(localTime)) {
            //5分钟前的进站人数和列车信息展示
            OutputWriteFileObject outputWriteFileObject = new OutputWriteFileObject();
            outputWriteFileObject.setNow(now);
            Map<String, List<BeforeFiveMinPeople>> bfmpMap = rootPublisher.getBeforeFiveMinPeople(now);
            List<SectCurInfoVo> sectCurInfoVoList = rootPublisher.getSectInfo(now);
            List<LineCurInfoVo> lineCurInfoVoList = rootPublisher.getLineCurInfoVoList(now);
//            List<LineCurInfoVo> lineCurInfoVoList = rootPublisher.getLineCurInfoVoList(now);
            for(int i=0;i<lineCurInfoVoList.size();i++){
                inputNetTotal=inputNetTotal+lineCurInfoVoList.get(i).getInputTotalLineNum();
            }
            NetCurInfoVo netCurInfo = rootPublisher.getNetCurInfo(now, transferStationMap, inputNetTotal);

            rootPublisher.sendSectInfo(now, startTime, sectCurInfoVoList);//发送断面信息---断面ID，断面名称，断面人数，断面车辆数
            rootPublisher.sendNetCurInfo(now, startTime, netCurInfo); //网络数据发送
            rootPublisher.sendLineCurInfo(now, startTime, lineCurInfoVoList);
            rootPublisher.sendPassFiveMinPeople(now, startTime, bfmpMap.get(now));
            rootPublisher.sendNetTrainInfo(now, startTime, trainCurInfoVos);


            outputWriteFileObject.setBfmpMap(bfmpMap);
            outputWriteFileObject.setSectCurInfoVoList(sectCurInfoVoList);
            outputWriteFileObject.setNetCurInfo(netCurInfo);
            outputWriteFileObject.setLineCurInfoVoList(lineCurInfoVoList);

//        outputWriteFileObject.setTrainCurInfoVos(trainCurInfoVos);
            return outputWriteFileObject; }

        else{
            return null;
        }

    }




    //线路静态数据更新
    public void  lineStaticDataUpdate(){
        LineStaticInfoVo lineStaticInfoVo = afterInitGetLineStaticInfo();
        UnitCache.lineStaticInfoVoMap.put(sceneCode,lineStaticInfoVo);
    }



    //本地硬盘数据输出
//    public void print2LocalStorage(String now, LocalTime startTime){
//        //向本地硬盘打印输出信息---线路信息
//        recorderRecord(now,startTime);
//        //车辆信息本地打印
//        rootPublisher.trainRecorderPublish(now);
//    }




    public void  setRootPublisherParam(){
        rootPublisher.setSceneCode(this.sceneCode);
    }

//    private void sectSenddata(String now, LocalTime startTime) {
//
//
//
//
//        if(startTime.isBefore(localTime))  {
//            Gson gson = new GsonBuilder().setPrettyPrinting().create();
//            String jsonResult = gson.toJson(sectCurInfoVoList);
//            try {
//                if (jsonResult != null) {
//                    MQTTUtils.send(CommonMQTTConstant.SIMSECTINFO, jsonResult);
//                }
//            }catch (Exception e){
//                e.printStackTrace();
//            }
//        }
//
//    }

    //网络数据发送
//    private void netDataSend(String now, LocalTime startTime) {
//        NetCurInfoVo netCurInfoVo=new NetCurInfoVo();
//        netCurInfoVo.setTimePt(now);
//
//        LocalTime localTime = LocalTime.parse(now);
//        Map<String, List<LineCurInfoVo>> lineCurInfoVoListMap = rootPublisher.getLineCurInfoVoListMap();
//        List<LineCurInfoVo> lineCurInfoVoList = lineCurInfoVoListMap.get(now);
//        int lsInputNum=0;
//        double lineFullLoadNum=0.0;
//        int trainNum=0;
//        for(LineCurInfoVo lineCurInfoVo : lineCurInfoVoList){
//            lsInputNum=lsInputNum+lineCurInfoVo.getInputInstantLineNum();
//            inputNetTotal=inputNetTotal+lsInputNum;
//            lineFullLoadNum=lineFullLoadNum+lineCurInfoVo.getTrainFullLoadLine();
//            trainNum=trainNum+lineCurInfoVo.getTrainOnLineNum();
//
//        }
//        int transferNum=0;
//
//       for (Map.Entry< String, TransferStation> transferStationEntry:transferStationMap.entrySet()){
//           TransferStation transferStation=transferStationEntry.getValue();
//           transferNum=transferNum+transferStation.getTransferPersonsMap().size();
//       }
//        netCurInfoVo.setInputNetInstantNum(lsInputNum);
//        netCurInfoVo.setInputNetTotalNum(inputNetTotal);
//        netCurInfoVo.setFullLoadNet(lineFullLoadNum);
//        netCurInfoVo.setNetTrainNum(trainNum);
//        netCurInfoVo.setSceneCode(this.sceneCode);
//        netCurInfoVo.setTransferNum(transferNum);
//        if(startTime.isBefore(localTime))  {
//
//            Gson gson = new GsonBuilder().setPrettyPrinting().create();
//            String jsonResult = gson.toJson(netCurInfoVo);
//
//            try {
//                if (jsonResult != null) {
//                    MQTTUtils.send(CommonMQTTConstant.SIMNETRUNINFO, jsonResult);
//                }
//            }catch (Exception e){
//                e.printStackTrace();
//            }
//
//        }
//
//
//    }

    private void checkStationStatus() {
        StationParamOperate stationParamOperate = UnitCache.stationParamOperateMap.get(sceneCode);
        if(stationParamOperate!=null){
            stationMap.forEach((k,v)->{
                if(stationParamOperate.getStationId().equals(v.getId())){
                    if(stationParamOperate!=null){
                        v.setOpen(stationParamOperate.isOpen());
                    }

                    if(stationParamOperate.getSpeedMap()!=null){
                        stationParamOperate.getSpeedMap().forEach((k1,v1)->{
                            v.getEntryExitGateMap().forEach((k2,v2)->{
                                if(k1.equals(v2.getEegName())){
                                    v2.setLimitSpeed(v1);
                                }
                            });
                        });

                    }


                }

            });

            UnitCache.stationParamOperateMap.put(sceneCode, null);
        }
    }


//    public void recorderRecord(String now,LocalTime startTime){
//        LocalTime localTime = LocalTime.parse(now);
////        lineCurInfoVoList.addAll(lineCurInfoVoList1);
////        if(startTime.isBefore(localTime)&& (localTime.getSecond() % 5 == 0))  {
//        if(startTime.isBefore(localTime)) {
//            for (Map.Entry<String, LineRooter> lineRooterEntry : lineRooterMap.entrySet()) {
//                lineRooterEntry.getValue().getReacorder().linePublishInfo(now);
//            }
//        }
//    }



    private void sendData(String now, LocalTime startTime, SceneParam sceneParam) {

    }

    //发送线路车辆运行信息的方法
    private void printAndSendNetParksInfo() {
        for (Map.Entry<String, List<Parker>> entry : parkerMap.entrySet()) {
            for (Parker parker : entry.getValue()) {
                System.out.println(parker);
            }
        }
    }


    //region 数据加载的旧代码

    //    按停车场分配的车辆，把车辆集合放入的停车场的集合中
//    public void setTrainListenerParam() {
//        this.offTrainNumRangeMap = simulatorParam.getOffTrainNumRangeMap();
//        trainListener.setOffTrainNumRangeMap(offTrainNumRangeMap);
//        trainListener.setParkersMap(this.parkersMap);
//        trainListener.setStationMap(this.stationMap);
//        trainListener.setLineRooterMap(this.lineRooterMap);
//        trainListener.setTransferNameStationMap(this.transferNameStationMap);
//        trainListener.setStationNameMap(this.stationLineStaionNameMap);
//        trainListener.setLineMap(lineMap);
//    }
    /**
     * @description: 初始化数据
     * 道路上下行
     * 包括，已有数据分配到线路---列车时刻表，
     * 分配的数据加工--列车数
     * 数据库数据查询--OD数据
     * 查询出的数据分配到线路和站点
     * @author:  renzhg
     * @date:  2024/11/16 9:47
     **/
//    public RooterInitializer initData() {
//        // 生成一个RooterInitializer实例
//        RooterInitializer rooterInitializer = generateRooterInitializer();
//        // 把站点对象分配给各个线路(列车生成-》车辆段;列车时刻表-》线路)
//        // 为每个线路路由器设置各种映射
//
//        newTrainAndOrbit2Line(rooterInitializer);
//
//        lineRooterMap.forEach((k, v) -> {
//            v.getLine().setSceneCode(sceneCode);
//            v.getLine().setT80RouteHisMap(t80RouteHisMap);
//            v.getLine().setStationNetMap(stationMap);
//            v.getLine().setTransferStationMap(transferStationMap);
//        });
//        // 设置乘客站点分布信息映射
//        rooterInitializer.setPsgStationDistributionInfoMap(psgStationDistributionInfoMap);
//        rooterInitializer.initTrainTableBizData();//列车时刻表生成列车动作列表,将人员分配到列车上、以及设置站点和换乘站数据。
//        rooterInitializer.queryODData2Line();    // 从数据库查出OD,分配给相应线路和站点
//      return rooterInitializer;
//    }
/**
 * @description: 初始化后，设置数据
 *
 * @author:  renzhg
 * @date:  2024/11/30 12:12
 **/
//    public void initAfterSetData(RooterInitializer rooterInitializer) {
//        // 获取未分配的地铁列车映射
//        metroTrainNoAssigeMap = rooterInitializer.getMetroTrainNoAssigeMap();
//        // 初始化每条线路的首班车时间
//        netStartTrainTime = rooterInitializer.initEveryLineFirstTrainStartTime();
//        rootPublicsherAssign();
//        // 确保网络首班车时间不早于04:00:00
//        if (TimeUtil.compareStrTimes("04:00:00", netStartTrainTime).equals("2")) {
//            netStartTrainTime = "04:00:00";
//        }
//    }

    //网络打印配置
//    private void rootPublicsherAssign() {
//        // 为根发布者设置线路路由器映射
//        rootPublisher.setLineRooterMap(lineRooterMap);
//        // 为每个线路路由器配置线路信息发布者
//        lineRooterMap.forEach((k, v) -> {
//            v.lineInfoPublisher.setLine(v.line);
//            v.lineInfoPublisher.setSceneCode(this.sceneCode);
//            v.lineInfoPublisher.setTrainManager(v.trainManager);
//            v.lineInfoPublisher.setStationInThisLineMap(v.getStationInThisLineMap());
//            v.lineInfoPublisher.setParkerMap(v.parkerMap);
//            v.reacorder.setSceneCode(this.sceneCode);
//            v.reacorder.setStationInThisLineMap(v.getStationInThisLineMap());
//        });
//    }
    /**
     * @description: 组装线网中个各个需要的参数，分配车辆给车辆段
     * 这个方法重要
     * 1、创建新车--->各个车辆段
     * 2、生成一个名字的站点字典
     * 3、生成一个id的站点字典
     * 4、生成上下行轨道轨道
     * 5、生成停车场--停车场中装配了列车数据
     * 6、组装到线路数据中
     * 7、分配路径到每个站点
     * 8、分配轨道到车站
     * @author:  renzhg
     * @date:  2024/11/16 10:09
     **/
//    private void newTrainAndOrbit2Line(RooterInitializer rooterInitializer) {
//
//        rooterInitializer.assemblyAction();//组装线路lineRooter
//        // 从rooterInitializer中设置线路映射
//        lineMap = rooterInitializer.getLineMap();
//        // 将路径映射到线路
//        rooterInitializer.path2Line();
//
//    }

//    public void routeAndStationMap2line() {
//
//    }

//    public RooterInitializer generateRooterInitializer() {
//        RooterInitializer rooterInitializer = new RooterInitializer();
//        rooterInitializer.setSceneCode(sceneCode);
//        rooterInitializer.setLineRooterMap(lineRooterMap);
//        rooterInitializer.setLineAllMap(lineAllMap);
//        rooterInitializer.setStationMap(stationMap);
//        rooterInitializer.setTransferStationMap(transferStationMap);
//        rooterInitializer.setPersonPathMap(personPathMap);
//        rooterInitializer.setPersonTrainMapByLine(personTrainMapByLine);
//        rooterInitializer.setLinesStationMap(linesStationMap);
//        rooterInitializer.setStationNameMap(stationNameMap);
//        rooterInitializer.setParkerMap(parkerMap);
//        rooterInitializer.setTrainPlanTableMapByLine(trainPlanTableMapByLine);
//        rooterInitializer.setPsgStationDistributionInfoMap(psgStationDistributionInfoMap);
//        rooterInitializer.setOdProbabilityApiInfoMap(odProbabilityApiInfoMap);
//        rooterInitializer.setNumPeopEnStationApiInfoMap(numPeopEnStationApiInfoMap);
//        rooterInitializer.initSceneCode2Line();
//        rooterInitializer.initLineStationMap();
//        return rooterInitializer;
//
//
//    }


    //region 统计线网方法
    //统计线网总人数


    //endregion
    //region 统计各线路方法
    //给定线路id,统计线路总人数
    //统计分线各站内人数
    //统计当前线路内在线列车数
    //endregion



    /**
     * @description: 列车时刻表装配
     * 列车时刻表转化为列车动作路径
     * 把列车摆放到响应的位置，如果是直接场段开始的就放在场段，如果是线网，则放在线网上
     * 同时把相应的列车动作表调整到对应位置上
     * 设定线路的每秒进网人数
     * @author: renzhg
     * @date: 2024/10/6 19:34
     **/



    //发送线路车辆段信息
    //发线路汇总信息
    //发送网络汇总信息

//    加载业务数据，包括列车时刻表（时刻表过滤分线路）、OD概率数据、进站人数数据
/**
 * @description: 加载业务数据，包括人员路径数据，列车时刻表（时刻表过滤分线路）、OD概率数据、每秒进站人数。
 *
 *
 * @author:  renzhg 
 * @date:  2024/11/29 11:00
 **/
//    public void loadBizData() {
////        RooterBizLoader rooterBizLoader = getRooterBizLoader();
////        trainPlanTableMapByLine = rooterBizLoader.getTrainPlanTableMapByLine();
////        personTrainMapByLine = rooterBizLoader.getPersonTrainMapByLine();
////        odProbabilityApiInfoMap = rooterBizLoader.getOdProbabilityApiInfoMap();
////        numPeopEnStationApiInfoMap = rooterBizLoader.getNumPeopEnStationApiInfoMap();
////        psgStationDistributionInfoMap = rooterBizLoader.getPsgStationDistributionInfoMap();
////        t80RouteHisMap = rooterBizLoader.getT80RouteHisMap();
////        generateHistoryPath(t80RouteHisMap);
//    }


//    public void generateHistoryPath(Map<String, List<RouteStation>> t80RouteHisMap) {
//        List<PersonPath> personPaths = new ArrayList<>();
//        t80RouteHisMap.forEach((k, v) -> {
//            v.sort(Comparator.comparingInt(rs -> Integer.parseInt(rs.stationSn)));
//            boolean isInPath = false;
//            List<PersonPathItem> personPathItemList = new ArrayList<>();
//            for (int i = 0; i < v.size(); i++) {
//                PersonPathItem personPathItem = new PersonPathItem();
//                personPathItem.setIndex(Integer.parseInt(v.get(i).getStationSn()));
//                personPathItem.setPathIndex(v.get(i).getStationSn());
//                personPathItem.setStationId(v.get(i).getStationId());
//                if (stationMap.get(v.get(i).getStationId()) == null) {
//                    isInPath = true;
//                } else {
//                    Station station = stationMap.get(v.get(i).getStationId());
//                    personPathItem.setStationName(station.getName());
//                    personPathItem.setLineId(station.getLine());
//                    if (isInTranserStation(station.getId())) {
//                        personPathItem.setTransfer(true);
//                    }
//                    personPathItem.setNeedTransfer(false);
//                }
//                personPathItemList.add(personPathItem);
//            }
//            if (!isInPath) {
//                List<PersonPathItem> personPathItemList1 = setPersonPathItemTransfered(personPathItemList);
//                PersonPath personPath = new PersonPath(personPathItemList1);
//
//
//                personPathMap.put(k + "_" + personPath.getFirst().getStationName(), personPath);
//                personPathIdMap.put(k + "_" + personPath.getFirst().getStationId(), personPath);
//                personPaths.add(personPath);
//
//
//            }
//        });
//        historyPersonPathMap = personPaths.stream().collect(Collectors.groupingBy(e -> e.getFirst().getStationName()));
//
//
////        historyPersonPathMap.put(k, personPaths);
//    }


//    private List<PersonPathItem> setPersonPathItemTransfered(List<PersonPathItem> personPathItemList) {
//        personPathItemList.sort(Comparator.comparingInt(PersonPathItem::getIndex));
//        for (int i = 1; i < personPathItemList.size(); i++) {
//            PersonPathItem previous = personPathItemList.get(i - 1);
//            PersonPathItem current = personPathItemList.get(i);
//            if (previous.getStationName().equals(current.getStationName())) {
//                previous.setNeedTransfer(true);
//            }
//        }
//
//        return personPathItemList;
//
//    }

//    private boolean isInTranserStation(String stationId) {
//        boolean isInTranserStation = false;
//        for (Map.Entry<String, TransferStation> entry : transferStationMap.entrySet()) {
//            if (entry.getValue().getTransferStationMap().containsKey(stationId)) {
//                isInTranserStation = true;
//                break;
//            }
//        }
//        return isInTranserStation;
//    }

    /**
     * @description: 加载业务数据，包括列车时刻表、OD概率数据和站点数据。
     *
     * 1、创建一个新的 RooterBizLoader 实例
     * 2、设置数据业务加载器
     * 3、设置历史业务列车加载服务
     * 4、设置历史业务人员加载服务
     * 5、设置路径信息服务的初始化信息，用来查询历史路径信息
     * 6、设置换乘站映射
     * 7、设置站点映射
     * 8、设置场景代码
     * 9、设置停车场映射
     * 10、设置停车场映射
     * 11、加载业务数据
     *
     * @author:  renzhg
     * @date:  2024/11/29 10:29
     **/
//    private @NotNull RooterBizLoader getRooterBizLoader() {
//        RooterBizLoader rooterBizLoader = new RooterBizLoader();
//        rooterBizLoader.setDataBizLoader(dataBizLoader);
//        rooterBizLoader.setHistoryBizTrainLoaderService(historyBizTrainLoaderService);
//        rooterBizLoader.setHistoryBizPersonLoaderService(historyBizPersonLoaderService);
//        rooterBizLoader.setT80RouteHisService(t80RouteHisService);
//        rooterBizLoader.setTransferStationMap(transferStationMap);
//        rooterBizLoader.setStationMap(stationMap);
//        rooterBizLoader.setSceneCode(sceneCode);
//        rooterBizLoader.setParkersMap(parkersMap);
//        rooterBizLoader.setParkerMap(parkerMap);
//        rooterBizLoader.loadBizData();
//        return rooterBizLoader;
//    }
//endregion

}
